#include "App_Task.h"

static void App_Task_MassageKeyHandle(KeyType_e keyType);
static void App_Task_FlankKeyHandle(KeyType_e keyType);
static void App_Task_LumbarSupportKeyHandle(KeyType_e keyType);

static void  App_Task_StartTaskFunction(void *args);
TaskHandle_t startTaskHandle;   /* start任务的句柄 */

static void  App_Task_MassageTaskFunction(void *args);
TaskHandle_t massageTaskHandle; /* massage任务的句柄 */

static void  App_Task_KeyTaskFunction(void *args);
TaskHandle_t keyTaskHandle;     /* key任务的句柄 */

/**
 * @brief 启动FreeRTOS
 *
 */
void App_Task_StartFreeRTOS(void)
{
    /* 初始化按摩模式 */
    App_Massage_Init();

    /* 初始化四向按键 */
    Inf_FourwayKey_Init();

    /* 初始化侧翼 */
    App_Flank_Init();

    /* 初始化腰托 */
    App_LumbarSupport_Init();

    /* 创建启动任务 */
    BaseType_t isCreateSuccess =
        xTaskCreate(App_Task_StartTaskFunction, /* 任务执行的函数 */
                    START_TASK_NAME, START_TASK_STACK_DEPTH, NULL, START_TASK_PRIORITY, &startTaskHandle);

    /* 判断是否启动成功 */
    if (isCreateSuccess == pdPASS) {
        LOG("Start task create success...\n");
    }
    else {
        LOG("Start task create fail...\n");
    }

    /* 3. 启动调度器 */
    vTaskStartScheduler();
}

/**
 * @brief Start task
 *
 */
static void App_Task_StartTaskFunction(void *args)
{
    LOG("Start task start...\n");

    /* 1. 创建按摩任务 */
    BaseType_t isCreateSuccess = xTaskCreate(App_Task_MassageTaskFunction, /* 任务执行的函数 */
                                             MASSAGE_TASK_NAME,            /* 任务名字 */
                                             MASSAGE_TASK_STACK_DEPTH,     /* 任务栈大小 */
                                             NULL,                         /* 任务参数 */
                                             MASSAGE_TASK_PRIORITY,        /* 任务优先级 */
                                             &massageTaskHandle);
    if (isCreateSuccess == pdPASS) {
        LOG("Massage task create success...\n");
    }
    else {
        LOG("Massage task create fail...\n");
    }

    /* 2. 创建按键任务 */
    isCreateSuccess = xTaskCreate(App_Task_KeyTaskFunction, /* 任务执行的函数 */
                                  KEY_TASK_NAME,            /* 任务名字 */
                                  KEY_TASK_STACK_DEPTH,     /* 任务栈大小 */
                                  NULL,                     /* 任务参数 */
                                  KEY_TASK_PRIORITY,        /* 任务优先级 */
                                  &keyTaskHandle);
    if (isCreateSuccess == pdPASS) {
        LOG("Key task create success...\n");
    }
    else {
        LOG("Key task create fail...\n");
    }

    /* 自杀 */
    vTaskDelete(NULL);
}

/**
 * @brief 按摩任务
 *
 */
static void App_Task_MassageTaskFunction(void *args)
{
    LOG("Massage task start...\n");

    uint32_t curTickCount = xTaskGetTickCount();

    while (1) {
        /* 如果不是按摩模式，跳过本次调度 */
        if (keyConfig.keyWorkMode != KEY_WORK_MODE_MASSAGE) {
            taskYIELD();
            continue;
        }

        if (massageConfig.massageResidueTime == 0) {
            App_Massage_Stop();
            taskYIELD();
            continue;
        }

        /* 开始按摩 */
        App_Massage_Start();

        vTaskDelayUntil(&curTickCount, pdMS_TO_TICKS(MASSAGE_TASK_CYCLE));
    }
}

/**
 * @brief 按键任务
 *
 */
static void App_Task_KeyTaskFunction(void *args)
{
    LOG("Key task start...\n");

    uint32_t  curTickCount = xTaskGetTickCount();
    KeyType_e keyType      = KEY_TYPE_NONE;

    while (1) {

        /* 选择按键回调函数 */
        Inf_FourwayKey_SelectKeyCallback(keyConfig.keyWorkMode);

        Inf_FourwayKey_TimerHandler();

        /* 根据不同的模式处理按键 */
        switch (keyConfig.keyWorkMode) {
        case KEY_WORK_MODE_MASSAGE:        App_Task_MassageKeyHandle(keyType); break;
        case KEY_WORK_MODE_FLANK:          App_Task_FlankKeyHandle(keyType); break;
        case KEY_WORK_MODE_LUMBAR_SUPPORT: App_Task_LumbarSupportKeyHandle(keyType); break;
        }

        vTaskDelayUntil(&curTickCount, pdMS_TO_TICKS(KEY_TASK_CYCLE));
    }
}

/**
 * @brief 腰托模式下按键处理
 *
 * @param keyType 按下的按键值
 */
static void App_Task_LumbarSupportKeyHandle(KeyType_e keyType)
{
    static bool       lastIsNONE       = false;
    static TickType_t lastKeyPressTime = 0;

    /* 接收按键队列 */
    if (xQueueReceive(keyReceiveQueue, &keyType, 0) == pdTRUE) {
        // 记录最后一次按键时间
        lastKeyPressTime = xTaskGetTickCount();

        /* 检查充气时间 */
        for (uint8_t i = 0; i < LUMBAR_SUPPORT_MAXSIZE; i++) {
            if (lumbarSupports[i].inflatedTime == FULL_PRESSURE_TIME_VALUE) {
                lastIsNONE = true;
            }
        }

        if (lastIsNONE) {
            lastIsNONE = false;

            // 只在按键状态变化时执行操作，避免重复调用
            switch (keyType) {
            case KEY_TYPE_UP:
                LOG("KEY_TYPE_UP...\n");
                App_LumbarSupport_UpAdjust();
                break;

            case KEY_TYPE_DOWN:
                LOG("KEY_TYPE_DOWN...\n");
                App_LumbarSupport_DownAdjust();
                break;

            case KEY_TYPE_LEFT:
                LOG("KEY_TYPE_LEFT...\n");
                App_LumbarSupport_BehindAdjust();
                break;

            case KEY_TYPE_RIGHT:
                App_LumbarSupport_PrevAdjust();
                LOG("KEY_TYPE_RIGHT...\n");
                break;
            }
        }
    }
    else {
        // 只有当按键释放超过一定时间（例如200ms）才停止操作
        if (!lastIsNONE && (xTaskGetTickCount() - lastKeyPressTime > pdMS_TO_TICKS(200))) {
            lastIsNONE = true;
            LOG("KEY_TYPE_NONE...\n");
            App_LumbarSupport_AllYTValvesStopped();
        }
    }
}

/**
 * @brief 被动侧翼模式下按键处理
 *
 * @param keyType 按下的按键值
 */
static void App_Task_FlankKeyHandle(KeyType_e keyType)
{
    static bool       lastIsNONE       = false;
    static TickType_t lastKeyPressTime = 0;

    /* 接收按键队列 */
    if (xQueueReceive(keyReceiveQueue, &keyType, 0) == pdTRUE) {
        // 记录最后一次按键时间
        lastKeyPressTime = xTaskGetTickCount();

        if (lastIsNONE) {
            lastIsNONE = false;

            // 只在按键状态变化时执行操作，避免重复调用
            switch (keyType) {
            /* 充气 */
            case KEY_TYPE_UP:
                LOG("KEY_TYPE_UP...\n");
                flanksConfig[FLANK_INDEX_PASSIVE_LEFT].inflationEnable  = true;
                flanksConfig[FLANK_INDEX_PASSIVE_RIGHT].inflationEnable = true;
                App_Flank_Inflation();
                break;
            /* 泄气 */
            case KEY_TYPE_DOWN:
                LOG("KEY_TYPE_DOWN...\n");
                flanksConfig[FLANK_INDEX_PASSIVE_LEFT].deflateEnable  = true;
                flanksConfig[FLANK_INDEX_PASSIVE_RIGHT].deflateEnable = true;
                App_Flank_Deflate();
                break;
            }
        }
    }
    else {
        // 只有当按键释放超过一定时间（例如200ms）才停止操作
        if (!lastIsNONE && (xTaskGetTickCount() - lastKeyPressTime > pdMS_TO_TICKS(200))) {
            lastIsNONE = true;
            App_Flank_Stop();
        }
    }
}

/**
 * @brief 按摩模式下按键处理
 *
 * @param keyType 按下的按键值
 */
static void App_Task_MassageKeyHandle(KeyType_e keyType)
{
    /* 接收按键队列 */
    if (xQueueReceive(keyReceiveQueue, &keyType, 0) == pdTRUE) {
        switch (keyType) {
        case KEY_TYPE_UP:
            App_Massage_ModelShift(CHANGE_WAY_INCREASE);
            LOG("Massage model increase...\n");
            break;
        case KEY_TYPE_DOWN:
            App_Massage_ModelShift(CHANGE_WAY_DECREASE);
            LOG("Massage model decrease...\n");
            break;
        case KEY_TYPE_LEFT:
            App_Massage_GearShift(CHANGE_WAY_INCREASE);
            LOG("Massage gear increase...\n");
            break;
        case KEY_TYPE_RIGHT:
            App_Massage_GearShift(CHANGE_WAY_DECREASE);
            LOG("Massage gear decrease...\n");
            break;
        }
    }
}
